package com.milling.business.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.milling.business.BusinessConstants;
import com.milling.business.GlobalVariable;
import com.milling.business.domain.*;
import com.milling.business.mapper.*;
import com.milling.business.service.IWmsConfigInfoService;
import com.milling.business.service.IWmsTaskInfoService;
import com.milling.common.core.redis.RedisCache;
import com.milling.common.utils.DateUtils;
import com.milling.common.utils.http.WmsApiUtils;
import com.milling.common.utils.modbus.ModbusServiceFactory;
import com.milling.common.utils.modbus.ModbusTcpService;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 配针信息Service业务层处理
 *
 * @author X
 * @date 2025-03-18
 */
@Service
public class WmsConfigInfoServiceImpl implements IWmsConfigInfoService
{
    private static final Logger logger = LoggerFactory.getLogger(WmsConfigInfoServiceImpl.class);

    @Autowired
    private WmsConfigInfoMapper wmsConfigInfoMapper;

    @Autowired
    private WmsTaskInfoMapper wmsTaskInfoMapper;

    @Autowired
    private IWmsTaskInfoService wmsTaskInfoService;

    @Autowired
    private WmsConfigSubMapper wmsConfigSubMapper;

    @Autowired
    private WmsConfigHoleMapper wmsConfigHoleMapper;

    @Value("${modbus.tcp.host}")
    private String host; // 从配置文件或命令行参数中读取

    @Value("${modbus.tcp.port}")
    private int port; // 从配置文件或命令行参数中读取

    @Value("${modbus.tcp.poolSize}")
    private int poolSize; // 从配置文件或命令行参数中读取

    @Value("${modbus.tcp.slaveId}")
    private int slaveId;

    @Autowired
    private IWmsConfigInfoService wmsConfigInfoService;

    // 获取Modbus服务实例
    private ModbusTcpService modbusTcpService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private WmsConfigSupplyMapper wmsConfigSupplyMapper;
    @Autowired
    private WmsCellInfoMapper wmsCellInfoMapper;
    @Autowired
    private WmsErpTaskMapper wmsErpTaskMapper;
    @Autowired
    private WmsNeedleCacheMapper wmsNeedleCacheMapper;

    // 添加初始化方法
    @PostConstruct
    public void init() {
        // 初始化 Modbus 服务
        modbusTcpService = ModbusServiceFactory.getModbusService(host, port, poolSize);
        logger.info("WmsConfigInfoServiceImpl Modbus服务初始化完成 - {}:{}", host, port);



        // 初始化扫码器连接
//        initConnection();
    }
    /**
     * 查询配针信息
     *
     * @param configId 配针信息主键
     * @return 配针信息
     */
    @Override
    public WmsConfigInfo selectWmsConfigInfoByConfigId(Long configId)
    {
        return wmsConfigInfoMapper.selectWmsConfigInfoByConfigId(configId);
    }

    /**
     * 查询配针信息列表
     *
     * @param wmsConfigInfo 配针信息
     * @return 配针信息
     */
    @Override
    public List<WmsConfigInfo> selectWmsConfigInfoList(WmsConfigInfo wmsConfigInfo)
    {
        return wmsConfigInfoMapper.selectWmsConfigInfoList(wmsConfigInfo);
    }

    /**
     * 新增配针信息
     *
     * @param wmsConfigInfo 配针信息
     * @return 结果
     */
    @Override
    public int insertWmsConfigInfo(WmsConfigInfo wmsConfigInfo)
    {
        wmsConfigInfo.setCreateTime(DateUtils.getNowDate());
        return wmsConfigInfoMapper.insertWmsConfigInfo(wmsConfigInfo);
    }

    /**
     * 修改配针信息
     *
     * @param wmsConfigInfo 配针信息
     * @return 结果
     */
    @Override
    public int updateWmsConfigInfo(WmsConfigInfo wmsConfigInfo)
    {
        wmsConfigInfo.setUpdateTime(DateUtils.getNowDate());
        return wmsConfigInfoMapper.updateWmsConfigInfo(wmsConfigInfo);
    }

    /**
     * 批量删除配针信息
     *
     * @param configIds 需要删除的配针信息主键
     * @return 结果
     */
    @Override
    public int deleteWmsConfigInfoByConfigIds(Long[] configIds)
    {
        for (int i = 0; i < configIds.length; i++) {
            Long configId = configIds[i];
            WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
            wmsTaskInfo.setConfigId(configId);
            List <WmsTaskInfo> wmsTaskInfos = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfo);
            for (int j = 0; j < wmsTaskInfos.size(); j++) {
                WmsTaskInfo wmsTaskInfo1 = wmsTaskInfos.get(j);
                wmsTaskInfoMapper.deleteWmsTaskInfoByTaskId(wmsTaskInfo1.getTaskId().toString());
            }

            WmsConfigSupply wmsConfigSupplyQuery = new WmsConfigSupply();
            wmsConfigSupplyQuery.setConfigId(configId);
            List<WmsConfigSupply> wmsConfigSupplyList = wmsConfigSupplyMapper.selectWmsConfigSupplyList(wmsConfigSupplyQuery);
            for (WmsConfigSupply wmsConfigSupply : wmsConfigSupplyList) {
                wmsConfigSupplyMapper.deleteWmsConfigSupplyById(wmsConfigSupply.getId());
            }

            WmsConfigSub wmsConfigSub = new WmsConfigSub();
            wmsConfigSub.setConfigId(configId);
            List <WmsConfigSub> wmsConfigSubs = wmsConfigSubMapper.selectWmsConfigSubList(wmsConfigSub);
            for (int j = 0; j < wmsConfigSubs.size(); j++) {
                WmsConfigSub wmsConfigSub1 = wmsConfigSubs.get(j);
                wmsConfigSubMapper.deleteWmsConfigSubByConfigSubId(wmsConfigSub1.getConfigSubId());
            }
        }

        return wmsConfigInfoMapper.deleteWmsConfigInfoByConfigIds(configIds);
    }

    /**
     * 删除配针信息信息
     *
     * @param configId 配针信息主键
     * @return 结果
     */
    @Override
    public int deleteWmsConfigInfoByConfigId(Long configId)
    {
        return wmsConfigInfoMapper.deleteWmsConfigInfoByConfigId(configId);
    }

    public void initConfigParam(){
        // 初始化基本类型参数
        redisCache.setCacheObject(GlobalVariable.PLC_501_VALUE, 0);
        redisCache.setCacheObject(GlobalVariable.START_VALUE, 0);
        redisCache.setCacheObject(GlobalVariable.WRITE_HOLES_FLAG, false);
        redisCache.setCacheObject(GlobalVariable.PLC_502_VALUE, 0);
        redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 0);
        redisCache.setCacheObject(GlobalVariable.CONFIG_BOX_ID, 0);

        // 初始化数组参数（创建包含16个空字符串的列表）
/*
        try {
            redisCache.deleteObject(GlobalVariable.CONFIG_BOX_CODE);
            redisCache.deleteObject(GlobalVariable.ALREADY_CODES);
            redisCache.deleteObject(GlobalVariable.ALREADY_STORAGE_CODES);
        } catch (Exception e) {
            logger.error("初始化时，删除数组缓存参数失败！");
            e.printStackTrace();
        }
        String[] emptyArray = new String[16];
        Arrays.fill(emptyArray, "");
        List<String> emptyList = Arrays.asList(emptyArray);
        redisCache.setCacheList(GlobalVariable.CONFIG_BOX_CODE, emptyList);

        redisCache.setCacheMap(GlobalVariable.ALREADY_CODES, new ConcurrentHashMap<>());
        redisCache.setCacheMap(GlobalVariable.ALREADY_STORAGE_CODES, new ConcurrentHashMap<>());
*/

        // 统一删除所有相关键（强制类型清理）
        String[] keysToDelete = {
                GlobalVariable.CONFIG_BOX_CODE,
                GlobalVariable.ALREADY_CODES,
                GlobalVariable.ALREADY_STORAGE_CODES
        };

        for (String key : keysToDelete) {
            try {
                // 添加重试机制应对Redis锁
                int retry = 0;
                while (retry < 3 && redisCache.hasKey(key)) {
                    redisCache.deleteObject(key);
                    retry++;
                    if (redisCache.hasKey(key)) Thread.sleep(50); // 短暂等待
                }
            } catch (Exception e) {
                logger.error("删除Redis键失败: {}", key, e);
            }
        }

        // 初始化基本类型参数（原有代码）
        // ...

        // 重新创建数据结构（关键修改点）
        redisCache.setCacheMap(GlobalVariable.CONFIG_BOX_CODE, new ConcurrentHashMap<String, String>()); // 不可变空集合更安全
        redisCache.setCacheMap(GlobalVariable.ALREADY_CODES, new ConcurrentHashMap<String, String>());
        redisCache.setCacheMap(GlobalVariable.ALREADY_STORAGE_CODES, new ConcurrentHashMap<String, String>());
    }

    public String startConfigTask(String macCode, WmsConfigSub wmsConfigSub){
//        启动，告知上料托盘数量  暂时写为1
        //上料托盘数据写入 D4999 - D5799
        //配针托盘够数的，每个孔位写入配针托盘ID号(1-84)
        //需补整盒的，每个孔位写入90
        //需补散料的，每个孔位写入100
        if(wmsConfigSub.getTrayId().intValue() == 1) {
            WmsConfigInfo wmsConfigInfo = wmsConfigInfoMapper.selectWmsConfigInfoByConfigId(wmsConfigSub.getConfigId());
            WmsErpTask wmsErpTask = wmsErpTaskMapper.selectWmsErpTaskById(wmsConfigInfo.getErpTaskId());
            String jsonString = wmsErpTask.getFullboxData();
            if (StringUtils.isNotEmpty(jsonString)) {
                //此处执行整盒叫料

                ObjectMapper mapper = new ObjectMapper();
                try {
                    // 解析 JSON 字符串为 JsonNode
                    JsonNode rootNode = mapper.readTree(jsonString);

                    WmsApiUtils wmsApiUtils = new WmsApiUtils();
                    // 遍历 JSON 数组
                    for (JsonNode node : rootNode) {
                        String drillInfo = node.get("drillInfo").asText();
                        int count = node.get("count").asInt();
                        logger.error("整盒直通下料料号信息：" + drillInfo + " 数量：" + count);

                        JSONObject queryJson = wmsApiUtils.genReqBodyDrillcount(drillInfo, BusinessConstants.DELIVER_PORT_RETURN, new Long(count));
                        String response = wmsApiUtils.requestMaterial(queryJson.toJSONString());

                        WmsTxnInfo wmsTxnInfo = new WmsTxnInfo();
                        wmsTxnInfo.setTxnType(BusinessConstants.TXN_TYPE_4);//后库来料 - 直通通道下料
                        wmsTxnInfo.setReqBody(queryJson.toJSONString());
                        wmsTxnInfo.setResBody(response);
                        wmsTxnInfo.setCreateTime(new Date());
                        wmsTxnInfo.setQty(new Long(count * 50));
                        wmsTxnInfo.setRemark("整盒直通下料，料号信息：" + drillInfo + " 数量：" + count);
                    }
                } catch (IOException e) {
                    logger.error("整盒叫料异常，解析JSON字符串失败");
                    e.printStackTrace();
                }




            }
        }


        Map<String, List<Integer>> fullBoxMaterialBoxNumbers = convertJsonToMap(wmsConfigSub.getFullData());
        for (Map.Entry<String, List<Integer>> entry : fullBoxMaterialBoxNumbers.entrySet()) {
            logger.info("生成整盒来料任务： " + fullBoxMaterialBoxNumbers.size());
            String drillinfo = entry.getKey();
            List<Integer> boxNumbers = entry.getValue();
            for (Integer boxNumber : boxNumbers) {
                wmsTaskInfoService.genWmsTaskInfo(macCode, BusinessConstants.TASK_TYPE_3, wmsConfigSub.getConfigId(), wmsConfigSub.getConfigSubId(), drillinfo, BusinessConstants.FULL_TYPE_FULL, 50, boxNumber, null);
            }
        }

        /**启动后库来料相机监听**/
        // 主线程可以继续处理其他逻辑（例如发送消息）
        try {
            //上料托盘数
            modbusTcpService.writeHoldingRegister(1, 500, 1);
            modbusTcpService.writeHoldingRegister(1, 600, 1);//配针
            modbusTcpService.writeCoil(1, 1, true);
            Thread.sleep(50);
            modbusTcpService.writeCoil(1, 1, false);
        } catch (ModbusTransportException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        // 调用配针机启动逻辑
        // 这里可以根据实际需求调用配针机的接口或执行其他操作
        // 例如：调用 Modbus TCP 服务发送启动指令
        return ""; // 返回操作结果
    }

    public Map<String, List<Integer>> convertJsonToMap(String jsonString) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(jsonString, Map.class);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Transactional
    public void genConfigSupply(WmsConfigInfo wmsConfigInfo) {
        Long erpTaskid = wmsConfigInfo.getErpTaskId();
        WmsErpTask wmsErpTask = wmsErpTaskMapper.selectWmsErpTaskById(erpTaskid);
        Map<String, Integer> map = new HashMap<>();
        JSONObject jsonObject = JSONObject.parseObject(wmsErpTask.getConfigData());
        JSONArray drillArray = jsonObject.getJSONArray("drillArray");
        for (int i = 0; i < drillArray.size(); i++) {
            JSONObject drillObject = drillArray.getJSONObject(i);
            String drillInfo = drillObject.getString("drillInfo");
            Integer drillCount = drillObject.getInteger("drillCount");
            if(map.get(drillInfo) == null){
                map.put(drillInfo, drillCount);
            } else {
                map.put(drillInfo, map.get(drillInfo) + drillCount);
            }
        }

        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            String key = entry.getKey();
            Integer value = entry.getValue();

// 如果 value 大于 50，则每 50 个单位写入一次数据库
            if (value > 50) {
                Integer v2 = value;
                while (v2 >= 50) {
                    WmsConfigSupply wmsConfigSupply = new WmsConfigSupply();
                    wmsConfigSupply.setConfigStatus(BusinessConstants.TASK_STATUS_1);
                    wmsConfigSupply.setConfigId(wmsConfigInfo.getConfigId());
                    wmsConfigSupply.setErpTaskId(wmsConfigInfo.getErpTaskId());
                    wmsConfigSupply.setDrillInfo(key);
                    wmsConfigSupply.setCreateTime(new Date());
                    wmsConfigSupplyMapper.insertWmsConfigSupply(wmsConfigSupply);
                    v2 -= 50; // 减去已处理的 50 个单位
                }

                // 如果剩余的 v2 大于 0 且小于 50，也写入数据库
                if (v2 > 0) {
                    WmsConfigSupply wmsConfigSupply = new WmsConfigSupply();
                    wmsConfigSupply.setConfigStatus(BusinessConstants.TASK_STATUS_1);
                    wmsConfigSupply.setConfigId(wmsConfigInfo.getConfigId());
                    wmsConfigSupply.setErpTaskId(wmsConfigInfo.getErpTaskId());
                    wmsConfigSupply.setDrillInfo(key);
                    wmsConfigSupply.setCreateTime(new Date());
                    wmsConfigSupplyMapper.insertWmsConfigSupply(wmsConfigSupply);
                }
            } else {
                WmsCellInfo wmsCellInfo = new WmsCellInfo();
                wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_3);
                wmsCellInfo.setDrillInfo(key);
                List<WmsCellInfo> wmsCellInfos = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfo);
                if(wmsCellInfos.size() > 0){
                    //缓存库里面有，无需补料
                } else {
                    // 如果 value 小于或等于 50，直接写入数据库
                    WmsConfigSupply wmsConfigSupply = new WmsConfigSupply();
                    wmsConfigSupply.setConfigStatus(BusinessConstants.TASK_STATUS_1);
                    wmsConfigSupply.setConfigId(wmsConfigInfo.getConfigId());
                    wmsConfigSupply.setErpTaskId(wmsConfigInfo.getErpTaskId());
                    wmsConfigSupply.setDrillInfo(key);
                    wmsConfigSupply.setCreateTime(new Date());
                    wmsConfigSupplyMapper.insertWmsConfigSupply(wmsConfigSupply);
                }
            }
        }

        startConfigSupply(wmsConfigInfo);
    }

    public void startConfigSupply(WmsConfigInfo wmsConfigInfo){
        WmsConfigSupply wmsConfigSupplyQuery = new WmsConfigSupply();
        wmsConfigSupplyQuery.setConfigId(wmsConfigInfo.getConfigId());
        wmsConfigSupplyQuery.setConfigStatus(BusinessConstants.SUPPLY_STATUS_1);
        List<WmsConfigSupply> wmsConfigSupplyList = wmsConfigSupplyMapper.selectWmsConfigSupplyList(wmsConfigSupplyQuery);

        wmsConfigSupplyQuery.setConfigStatus(BusinessConstants.SUPPLY_STATUS_2);
        List<WmsConfigSupply> wmsConfigSupplyIngList = wmsConfigSupplyMapper.selectWmsConfigSupplyList(wmsConfigSupplyQuery);
        int supplyCount = wmsConfigSupplyList.size();// - wmsConfigSupplyIngList.size();
        int total = 5;
        int tempTotal = 0;
        if(supplyCount > 0){
            tempTotal = total - wmsConfigSupplyIngList.size();
        }
        supplyCount = tempTotal > supplyCount ? supplyCount : tempTotal;
        if(wmsConfigSupplyList.size() > 0){
            WmsConfigSupply wmsConfigSupply = wmsConfigSupplyList.get(0);

            WmsCellInfo wmsCellInfo = new WmsCellInfo();
            wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_1);
            List<WmsCellInfo> wmsCellInfoList = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfo);
            try {
                if(wmsCellInfoList.size() > 0){
                    logger.error("startConfigSupply 补料 整盒呼叫");
                    WmsApiUtils wmsApiUtils = new WmsApiUtils();
                    JSONObject queryJson = wmsApiUtils.genReqBody(wmsConfigSupply.getDrillInfo(), BusinessConstants.DELIVER_PORT_REQUEST_MATERIAL);
                    String response = wmsApiUtils.requestMaterial(queryJson.toJSONString());

                    JSONObject jsonObject2 = JSONObject.parseObject(response);
                    // 提取顶层字段
                    String code = jsonObject2.getString("Code");
                    String message = jsonObject2.getString("Message");
                    if("ok".equals(message)) {

                        modbusTcpService.writeCoil(1, 1, true);
                        Thread.sleep(50);
                        modbusTcpService.writeCoil(1, 1, false);
                        modbusTcpService.writeHoldingRegister(slaveId, 600, 2);//缓存库补料
                        logger.info("[PLC]D600写入2 完成");

                        for (int i = 0; i < supplyCount; i++) {
                            wmsConfigSupply.setConfigStatus(BusinessConstants.TASK_STATUS_2);
//                            wmsConfigSupply.setUpdateTime(new Date());
                            wmsConfigSupply.setStartTime(new Date());
                            wmsConfigSupplyMapper.updateWmsConfigSupply(wmsConfigSupply);
                        }

                        if(!BusinessConstants.SUPPLY_STATUS_2.equals(wmsConfigInfo.getSupplyStatus())) {
                            wmsConfigInfo.setSupplyStatus(BusinessConstants.SUPPLY_STATUS_2);
                            wmsConfigInfo.setUpdateTime(new Date());
                            wmsConfigInfoMapper.updateWmsConfigInfo(wmsConfigInfo);
                        }
                    }
                    logger.info("补料任务启动成功");
                }
            } catch (ModbusTransportException e) {
                e.printStackTrace();
                throw new RuntimeException("modbus write error");
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("启动补料任务失败");
            }
        } else {
            if(wmsConfigSupplyIngList.size() == 0) {
                try {
                    modbusTcpService.writeHoldingRegister(slaveId, 600, 0);//缓存库补料完成
                    logger.info("补料任务结束");
                } catch (ModbusTransportException e) {
                    e.printStackTrace();
                }

                wmsConfigInfo.setSupplyStatus(BusinessConstants.SUPPLY_STATUS_5);
                wmsConfigInfo.setUpdateTime(new Date());
                wmsConfigInfoMapper.updateWmsConfigInfo(wmsConfigInfo);
            }
        }
    }

    @Override
    public void rollbackData() {
        //配刀托盘数据处理
        WmsNeedleCache wmsNeedleCacheQuery = new WmsNeedleCache();
        //回流中，需回滚为有货  1空闲，2有货，3回流中，4补料中
        wmsNeedleCacheQuery.setStatus(BusinessConstants.NEEDLE_STATUS_3);
        List<WmsNeedleCache> returnList = wmsNeedleCacheMapper.selectWmsNeedleCacheList(wmsNeedleCacheQuery);
        for (int i = 0; i < returnList.size(); i++) {
            WmsNeedleCache wmsNeedleCache = returnList.get(i);
            wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_2);
            wmsNeedleCache.setUpdateTime(new Date());
            wmsNeedleCacheMapper.updateWmsNeedleCache(wmsNeedleCache);
        }

        //补料中，需回滚为空闲
        wmsNeedleCacheQuery.setStatus(BusinessConstants.NEEDLE_STATUS_4);
        List<WmsNeedleCache> supplyList = wmsNeedleCacheMapper.selectWmsNeedleCacheList(wmsNeedleCacheQuery);
        for (int i = 0; i < supplyList.size(); i++) {
            WmsNeedleCache wmsNeedleCache = supplyList.get(i);
            wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_1);
            wmsNeedleCache.setUpdateTime(new Date());
            wmsNeedleCacheMapper.updateWmsNeedleCache(wmsNeedleCache);
        }

        //补料中，需回滚为空闲
        wmsNeedleCacheQuery.setStatus(BusinessConstants.NEEDLE_STATUS_5);
        supplyList = wmsNeedleCacheMapper.selectWmsNeedleCacheList(wmsNeedleCacheQuery);
        for (int i = 0; i < supplyList.size(); i++) {
            WmsNeedleCache wmsNeedleCache = supplyList.get(i);
            wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_1);
            wmsNeedleCache.setUpdateTime(new Date());
            wmsNeedleCacheMapper.updateWmsNeedleCache(wmsNeedleCache);
        }

        //缓存库数据处理
        WmsCellInfo wmsCellInfoQuery = new WmsCellInfo();
        //入库中2，需处理为空闲1
        wmsCellInfoQuery.setCellStatus(BusinessConstants.CELL_STATUS_2);
        List<WmsCellInfo> inList = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfoQuery);
        for (int i = 0; i < inList.size(); i++) {
            WmsCellInfo wmsCellInfo = inList.get(i);
            wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_1);
            wmsCellInfo.setUpdateTime(new Date());
            wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfo);
        }

        //出库中4，需处理为有货3
        wmsCellInfoQuery.setCellStatus(BusinessConstants.CELL_STATUS_4);
        List<WmsCellInfo> outList = wmsCellInfoMapper.selectWmsCellInfoList(wmsCellInfoQuery);
        for (int i = 0; i < outList.size(); i++) {
            WmsCellInfo wmsCellInfo = outList.get(i);
            wmsCellInfo.setCellStatus(BusinessConstants.CELL_STATUS_3);
            wmsCellInfo.setUpdateTime(new Date());
            wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfo);
        }

        //处理中 的TASK，直接删除
        WmsTaskInfo wmsTaskInfoQuery = new WmsTaskInfo();
        wmsTaskInfoQuery.setTaskStatus(BusinessConstants.TASK_STATUS_2);
        List<WmsTaskInfo> processingTasks = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfoQuery);
        for (int i = 0; i < processingTasks.size(); i++) {
            WmsTaskInfo wmsTaskInfo = processingTasks.get(i);
            wmsTaskInfoMapper.deleteWmsTaskInfoByTaskId(wmsTaskInfo.getTaskId().toString());
        }

        //待处理 的TASK，直接删除
        wmsTaskInfoQuery.setTaskStatus(BusinessConstants.TASK_STATUS_1);
        List<WmsTaskInfo> pendingTasks = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfoQuery);
        for (int i = 0; i < pendingTasks.size(); i++) {
            WmsTaskInfo wmsTaskInfo = pendingTasks.get(i);
            wmsTaskInfoMapper.deleteWmsTaskInfoByTaskId(wmsTaskInfo.getTaskId().toString());
        }

    }

    public Boolean mixHalf(Long configSubId) {
        syncPlcDrills(configSubId);

        //计算出有几个 待补料 任务数
        int pendings = 0;
        WmsTaskInfo wmsTaskInfoQuery = new WmsTaskInfo();
        wmsTaskInfoQuery.setConfigSubId(configSubId);
        wmsTaskInfoQuery.setTaskType(BusinessConstants.TASK_TYPE_1);
        wmsTaskInfoQuery.setTaskStatus(BusinessConstants.TASK_STATUS_1);
        List<WmsTaskInfo> wmsTaskInfos = wmsTaskInfoMapper.selectWmsTaskInfoList(wmsTaskInfoQuery);
        if(null != wmsTaskInfos && wmsTaskInfos.size() > 0) {
            pendings = wmsTaskInfos.size();
        }
        if(pendings == 0) {
//            return false;
            //没有补料任务了，切托盘；
            return true;
        }

        //计算出还有几个已补料(向PLC写入了补料数据)但未执行的任务数
        WmsConfigHole wmsConfigHoleQuery2 = new WmsConfigHole();
        wmsConfigHoleQuery2.setConfigSubId(configSubId);
        List pendingList = wmsConfigHoleMapper.getPendingDrills(wmsConfigHoleQuery2);
        int pendingDrills = pendingList.size();

        if(pendingDrills >= pendings) {
            logger.info("未补料任务 {} 个， 已补料未插针任务 {} 个，补料过半，切托盘");
            //补料过半，切托盘
            return true;
        }

        return false;
    }

    public void syncPlcDrills(Long configSubId) {
        boolean[] plcDrills = new boolean[800];
        try {
            //从PLC读取插针数据
            plcDrills = modbusTcpService.readCoils(slaveId, 5000, 800);
        } catch (ModbusTransportException e) {
            logger.error("modbus read error");
            throw new RuntimeException(e);
        }
        //从数据库读取插针数据
//            short[] configDrills = modbusTcpService.readHoldingRegisters(slaveId, 5000, 5800);
        WmsConfigHole wmsConfigHoleQuery = new WmsConfigHole();
        wmsConfigHoleQuery.setConfigSubId(configSubId);
        List<WmsConfigHole> wmsConfigHoles = wmsConfigHoleMapper.selectWmsConfigHoleList(wmsConfigHoleQuery);

        for (int i = 0; i < plcDrills.length; i++) {
            boolean plcDrill = plcDrills[i];
            if (plcDrill) {
                WmsConfigHole wmsConfigHole = wmsConfigHoles.get(i);
                if(wmsConfigHole.getStatus().equals("0")) {
                    //PLC已插针，PC未修改插针状态，则修改为已插针
                    wmsConfigHole.setStatus("1");
                    wmsConfigHoleMapper.updateWmsConfigHole(wmsConfigHole);
                }
            }
        }
    }


}
